import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:get/get.dart';
import 'package:jm_flutter_common/jm_flutter_common.dart';

import 'package:universal_io/io.dart';

import '../../config.dart';
import '../common.dart';

BuildContext? _I_18N_Context;

const kapplanguege = "kapplanguege";

class I18n {
  static const tag = "I18n";
  static String _systemLanguageCode = "";
  static String _languageCode = "system";
  static late Locale _locale;
  static FlutterI18nDelegate? _flutterI18nDelegate;
  static final Set<String> _textSetRecord = {}; //记录未翻译文本
  static bool autoRecordText = false; //是否自动记录未翻译文本
  static final List<AppLanguage> _languages = [
    AppLanguage(name: "跟随系统", code: "system"),
    AppLanguage(name: "English", code: "en"),
    AppLanguage(name: "简体中文", code: "zh"),
  ];
  static String forcedLanguageCode = "";

  static String defaultLanguage = "system";

  static List<AppLanguage> get languages => _languages;

  static List<String> get textSetRecord => _textSetRecord.toList();

  static String get languageCode => _languageCode;

  static String get languageName {
    if (_languageCode == "system") {
      return _languages
          .firstWhere((element) => element.code == _languageCode)
          .name;
    }
    return _languages
        .firstWhere((element) => element.code == _languageCode)
        .name;
  }

  static String get systemLanguage => _systemLanguageCode;

  static Locale get locale => _locale;

  static bool get isSystemCn {
    if (_systemLanguageCode.contains("zh")) {
      return true;
    }

    return false;
  }

  static bool get isAppCn {
    if (_languageCode == "system") {
      if (_systemLanguageCode.contains("zh")) {
        return true;
      }
    } else {
      if (_languageCode.contains("zh")) {
        return true;
      }
    }

    return false;
  }

  static bool get isAuto {
    return _languageCode == "system";
  }

  static String get appLanguageCode {
    if (_languageCode == "system") {
      return _systemLanguageCode;
    }
    return _languageCode;
  }

  static void setLanguages(List<AppLanguage> list, {bool system = true}) {
    _languages.clear();
    if (system) {
      _languages.add(AppLanguage(name: "跟随系统", code: "system"));
    }
    _languages.addAll(list);
  }

  static TransitionBuilder initBuilder(TransitionBuilder builder) {
    return (BuildContext context, Widget? child) {
      _I_18N_Context = context;
      return builder(context, child);
    };
  }

  static void init() async {
    if (!JmConfig.i18nEnable) {
      return;
    }
    _languageCode = Storage.read(kapplanguege, defVal: defaultLanguage);
    logd(tag, "当前APP语言:$_languageCode, autoRecordText:$autoRecordText");
    // if (autoRecordText) {
    //   //读取assets/i18n/text.json
    //   final textJson = await rootBundle.loadString("assets/i18n/zh.json");
    //   final textMap = jsonDecode(textJson);
    //   _textSet.addAll(textMap.keys);
    //   logd(tag, "textSet size:${_textSet.length}");
    // }
  }

  static FlutterI18nDelegate delegateOf(BuildContext context) {
    _flutterI18nDelegate ??= FlutterI18nDelegate(
      translationLoader: FileTranslationLoader(
        useCountryCode: false,
        fallbackFile: JmConfig.i18nFallbackFile,
        basePath: JmConfig.i18nBasePath,
        forcedLocale: Locale(_getLanguageCodeStr()),
      ),
      missingTranslationHandler: _missingTranslationHandler,
    );

    return _flutterI18nDelegate!;
  }

  static void setLanguage(AppLanguage appLanguage) async {
    if (_I_18N_Context == null) {
      return;
    }

    logd(tag, "修改语言:$_languageCode->${appLanguage.code}");
    if (_languageCode != appLanguage.code) {
      _languageCode = appLanguage.code;
      Storage.write(kapplanguege, _languageCode);
      await FlutterI18n.refresh(_I_18N_Context!, Locale(_getLanguageCodeStr()));
      Get.updateLocale(Locale(_getLanguageCodeStr()));
    }
  }

  static String _getLanguageCodeStr() {
    if (forcedLanguageCode.isNotEmpty) {
      return forcedLanguageCode;
    }

    String langStr = "en";

    if (_languageCode == "system") {
      final localeName = Platform.localeName;
      String systemLanguageCode = localeName.split('_')[0];
      _systemLanguageCode = systemLanguageCode;

      logd(tag, "当前系统语言:$_systemLanguageCode, localeName:$localeName");

      if (_systemLanguageCode.isNotEmpty) {
        langStr = _systemLanguageCode;
      } else {
        langStr = "en";
      }

      if (langStr == "zh") {
        //如果localeName包含TW
        if (localeName.contains("TW") ||
            localeName.contains("HK") ||
            localeName.contains("MO") ||
            localeName.contains("Hant")) {
          langStr = "zh_TW";
        }
      }
    } else {
      langStr = _languageCode;
      _locale = Locale(langStr);
    }

    return langStr;
  }

  // 缓存正则表达式以避免重复创建
  static final RegExp _chineseRegex = RegExp(r'[\u4e00-\u9fa5]');

  /// 缺少翻译时的处理方法
  static void _missingTranslationHandler(String key, Locale? locale) {
    // 使用缓存的正则表达式，避免每次调用都创建新的RegExp对象
    if (_chineseRegex.hasMatch(key)) {
      logw(tag, "缺少翻译 Key: $key, languageCode: ${locale!.languageCode}");
      if (autoRecordText) {
        // 如果包含中文字符，则不忽略，直接记录
        final result = _textSetRecord.add(key);
        if (result) {
          logd(tag, "记录未翻译文本: $key");
        }
      }
    }
  }

  ///清理未翻译文本
  static void clearTextSetRecord() {
    _textSetRecord.clear();
  }

  //导出未翻译文本为json字符串
  static String exportTextSetRecordJsonStr() {
    logd(tag, "导出未翻译文本: ${_textSetRecord.length}");
    if (_textSetRecord.isEmpty) {
      logd(tag, "未翻译文本为空");
      return "";
    }

    final textSetRecordMap = {};
    for (var key in _textSetRecord) {
      textSetRecordMap[key] = key;
    }
    final textJson = jsonEncode(textSetRecordMap);
    return textJson;
  }

  //导出未翻译文本为json文件
  static Future<String> exportTextSetRecordJsonFile() async {
    logd(tag, "导出未翻译文本为json文件");
    final textJson = exportTextSetRecordJsonStr();
    if (textJson.isEmpty) {
      return "";
    }

    final textFile = File(
        "${JmConfig.appTempPath}/i18n_record_${DateTime.now().toNumFull}.json");
    await textFile.writeAsString(textJson);
    return textFile.path;
  }
}

class AppLanguage {
  String name;
  String code;

  AppLanguage({this.name = "", this.code = ""});
}

String i18n(final String key) {
  if (JmConfig.i18nEnable && _I_18N_Context != null) {
    return FlutterI18n.translate(_I_18N_Context!, key);
  }
  return key;
}

extension StringI18n on String {
  String get i18n {
    if (JmConfig.i18nEnable && _I_18N_Context != null) {
      return FlutterI18n.translate(_I_18N_Context!, this);
    }
    return this;
  }

  String i18nEnabled(bool enable) {
    if (JmConfig.i18nEnable && enable && _I_18N_Context != null) {
      return FlutterI18n.translate(_I_18N_Context!, this);
    }
    return this;
  }
}

extension ListStringI18n on List<String> {
  String i18n(Set<int> ignoreSet) {
    final sb = StringBuffer();
    for (int i = 0; i < length; i++) {
      if (ignoreSet.contains(i)) {
        sb.write(this[i]);
      } else {
        sb.write(this[i].i18n);
      }
    }
    return sb.toString();
  }
}
